import subprocess
import sys
import os
import shutil
from pathlib import Path

def install_playwright_browsers():
    """安装Playwright浏览器"""
    print("正在安装Playwright浏览器...")
    try:
        # 安装Chromium浏览器
        result = subprocess.run([
            sys.executable, "-m", "playwright", "install", "chromium"
        ], capture_output=True, text=True, timeout=600)
        
        if result.returncode == 0:
            print("Playwright浏览器安装完成")
            return True
        else:
            print(f"安装Playwright浏览器失败: {result.stderr}")
            return False
    except Exception as e:
        print(f"安装Playwright浏览器失败: {e}")
        return False

def get_playwright_browsers_path():
    """获取Playwright浏览器安装路径"""
    try:
        # 方法1: 直接获取Playwright浏览器默认安装路径
        home_path = Path.home()
        browsers_path = home_path / "AppData" / "Local" / "ms-playwright"
        
        if browsers_path.exists():
            print(f"找到Playwright浏览器路径: {browsers_path}")
            return browsers_path
        
        # 方法2: 使用playwright命令获取路径
        result = subprocess.run([
            sys.executable, "-m", "playwright", "install", "--dry-run"
        ], capture_output=True, text=True, timeout=30)
        
        if result.returncode == 0:
            lines = result.stdout.strip().split('\n')
            for line in lines:
                # 查找包含.ms-playwright的路径
                if 'ms-playwright' in line and 'C:' in line:
                    # 提取路径
                    start_pos = line.find('C:')
                    if start_pos != -1:
                        # 找到路径结束位置
                        path_part = line[start_pos:]
                        # 移除可能的额外文本
                        path_end = path_part.find(' chromium')
                        if path_end != -1:
                            path_part = path_part[:path_end]
                        
                        path_part = path_part.strip().split()[0]  # 获取第一个路径
                        path_obj = Path(path_part).parent  # 获取上级目录
                        
                        if path_obj.exists():
                            print(f"找到Playwright浏览器路径: {path_obj}")
                            return path_obj
        
        # 方法3: 查找常见的Playwright路径
        common_paths = [
            home_path / "AppData" / "Local" / "ms-playwright",
            home_path / ".cache" / "ms-playwright",
        ]
        
        for path in common_paths:
            if path.exists():
                print(f"找到Playwright浏览器路径: {path}")
                return path
                
        print("未找到Playwright浏览器路径")
        return None
    except Exception as e:
        print(f"获取浏览器路径失败: {e}")
        return None

def create_spec_file():
    """创建PyInstaller spec文件"""
    # 获取Playwright浏览器路径
    browsers_path = get_playwright_browsers_path()
    
    spec_content = '''
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['run.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[
        'playwright',
        'playwright.sync_api',
        'playwright.async_api',
        'playwright._impl._driver',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

'''
    
    # 如果找到了浏览器路径，则添加到datas中
    if browsers_path and browsers_path.exists():
        spec_content += f'''
# 添加Playwright浏览器文件
import os
from pathlib import Path

browsers_path = r'{browsers_path}'
if os.path.exists(browsers_path):
    try:
        # 只添加实际的浏览器目录
        for browser_dir in Path(browsers_path).iterdir():
            if browser_dir.is_dir() and ('chromium' in browser_dir.name.lower() or 'firefox' in browser_dir.name.lower() or 'webkit' in browser_dir.name.lower()):
                a.datas += Tree(str(browser_dir), prefix=f'playwright-browsers/{{browser_dir.name}}', excludes=['*.py', '*.pyc', '*.pyo', '__pycache__'])
            elif browser_dir.is_file() and browser_dir.suffix in ['.exe', '.dll']:
                a.datas += [(f'playwright-browsers/{{browser_dir.name}}', str(browser_dir), 'DATA')]
    except Exception as e:
        print(f"添加浏览器文件时出错: {{e}}")
'''
    else:
        print("警告: 未找到Playwright浏览器路径，将在运行时安装")
    
    spec_content += '''
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='easyTool',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
)
'''
    
    with open('build.spec', 'w', encoding='utf-8') as f:
        f.write(spec_content)
    print("已创建build.spec文件")

def build_executable():
    """构建可执行文件"""
    print("开始构建可执行文件...")
    try:
        # 使用spec文件构建
        result = subprocess.run([
            sys.executable, "-m", "PyInstaller", "build.spec"
        ], check=True)
        print("构建完成！")
        return True
    except subprocess.CalledProcessError as e:
        print(f"构建失败: {e}")
        return False

def main():
    """主函数"""
    print("开始打包流程...")
    
    # 1. 安装Playwright浏览器
    if not install_playwright_browsers():
        print("Playwright浏览器安装失败，退出打包流程")
        return False
    
    # 2. 创建spec文件
    create_spec_file()
    
    # 3. 构建可执行文件
    if build_executable():
        print("打包成功完成！")
        print("可执行文件位于 dist/easyTool.exe")
        return True
    else:
        print("打包失败")
        return False

if __name__ == "__main__":
    main()